/*
 * @Author: 崔骁 cuixiao@internal.ths.com.cn
 * @Date: 2022-10-17 15:57:52
 * @LastEditors: 崔骁 cuixiao@internal.ths.com.cn
 * @LastEditTime: 2023-03-14 13:32:22
 * @FilePath: /EEEWork/src/utils/map-service.ts
 * @Description:
 *
 * Copyright (c) 2022 by 崔骁 cuixiao@internal.ths.com.cn, All Rights Reserved.
 */
import { loadModules } from 'esri-loader';
// import Pbf from 'pbf';
// import geobuf from 'geobuf';
// import { getMapRiverData } from './http';
declare let turf: any;
// const imgHttp = ProConfig.imgIcon + 'map/';
// const imgHttp = 'http://222.212.88.209:18083/EEEWork/assets/img/map/';
// // 获取pbf数据
// export function getPbfData(): Promise<any> {

// 	return new Promise((resolve) => {
// 		getMapRiverData({}, false, 'arraybuffer').then((res: any) => {
// 			if (res !== 'error') {
// 				const data = geobuf.decode(new Pbf(res));
// 				console.log(data);
// 				resolve(data);
// 			}
// 		});
// 	});
// }

/**
 * 创建普通图层
 * @param options 图层配置项
 * @returns
 */
export function createGraphicsLayer(options: {
	id: string; // 图层ID
	visible: true; // 是否默认显示
	opacity: 1; // 透明度
}): Promise<any> {
	return new Promise((resolve) => {
		loadModules(['esri/layers/GraphicsLayer']).then(([GraphicsLayer]) => {
			resolve(new GraphicsLayer(options));
		});
	});
}
/**
 * 获取地图中心点
 * @param map 目标地图
 */
export function getMapCenter(map: any): { x: number; y: number } {
	return map.geographicExtent.getCenter();
}

/**
 * 设置地图可视化区域
 * @param map 地图对象
 * @param layer 图层
 */
export function setMapExtent(map: any, layer: any, wkid = 4326, offset= 0.06) {
	loadModules(["esri/geometry/Extent", "esri/graphicsUtils"]).then(([Extent, graphicsUtils]) => {
		// debugger
		if (layer.graphics && layer.graphics.length) {
			setTimeout(() => {
				const extent: {
                    xmax: number;
                    xmin: number;
                    ymax: number;
                    ymin: number;
                    spatialReference: {
                      wkid: number;
                    };
                  } = graphicsUtils.graphicsExtent(layer.graphics);
                  extent.xmax =
                      extent.xmax + offset > 180 ? extent.xmax : extent.xmax + offset;
                  extent.xmin =
                      extent.xmin - offset < -180
                          ? extent.xmin
                          : extent.xmin - offset;
                extent.ymax = extent.ymax + offset > 90 ? extent.ymax : extent.ymax + offset;
				extent.ymin = extent.ymin - offset < -90 ? extent.ymin : extent.ymin - offset;
				map.setExtent(extent);
				// setTimeout(() => {
				// 	map.setZoom(map.getZoom() - 1);
				// }, 500);
			}, 500)

		} else {
			setTimeout(() => {
				const extent: {
					xmax: number;
					xmin: number;
					ymax: number;
					ymin: number;
					spatialReference: {
						wkid: number;
					};
				} = layer.fullExtent;
				extent.xmax =
					extent.xmax + offset > 180 ? extent.xmax : extent.xmax + offset;
				extent.xmin =
					extent.xmin - offset < -180
						? extent.xmin
						: extent.xmin - offset;
				extent.ymax =
					extent.ymax + offset > 90 ? extent.ymax : extent.ymax + offset;
				extent.ymin =
					extent.ymin - offset < -90
						? extent.ymin
						: extent.ymin - offset;
				map.setExtent(extent);
			}, 500);
		}
	})
}

export function setMapCenter(map: any ,x: number, y: number, wkid = 4326){
	loadModules([
		'esri/geometry/Point',
	]).then(([ Point ]) => {
		const point = new Point(Number(x), Number(y));
		map.centerAt(point);
	});
}

/**
 * 地址打点
 * @param x 经度
 * @param y 纬度
 * @param graphicsLayer 图层
 * @param attrTemplate 属性
 * @param infoTemplate 模版
 */
// eslint-disable-next-line
export function addMarker(
	x: string | number,
	y: string | number,
	graphicsLayer: any,
	attrTemplate: any,
	infoTemplate: any,
	img: any,
	width: any,
	height: any,
	offsetX = 0,
	offsetY = 0,
) {
	return new Promise((reslove) => {
		loadModules([
			'esri/symbols/PictureMarkerSymbol',
			'esri/symbols/Font',
			'esri/symbols/TextSymbol',
			'esri/graphic',
			'esri/geometry/Point',
			'esri/SpatialReference'
		]).then(([PictureMarkerSymbol, Font, TextSymbol, Graphic, Point, SpatialReference]) => {
			// console.log(attrTemplate);
			const pictureMarkerSymbol = new PictureMarkerSymbol(img, width, height);
			pictureMarkerSymbol.setOffset(offsetX, offsetY);
			// const point = new Point(Number(x), Number(y)); // {"x": -122.65, "y": 45.53, "spatialReference": {"wkid": 4326 } }
			const point = new Point({ "x": Number(x), "y": Number(y), "spatialReference": { "wkid": 4326 } });
			// 创建Graphic
			const graphicPic = new Graphic(point, pictureMarkerSymbol, attrTemplate, infoTemplate);
			// console.log(graphicPic);
			// 图层增加图片点
			graphicsLayer.add(graphicPic);
			reslove(graphicPic);
		});
	});
}

/**
 * 添加文字点位图层
 * @param data 点位数据
 * @param graphicsLayer 图层
 * @param picUrl 图片地址
 * @param text 文字描述
 * @param offsetWidth 图片偏移宽度
 * @param offsetHeight 图片偏移高度
 * @param attrTemplate 属性列表
 * @param infoTemplate 信息框
 */
export function addTextLabel(
	data: { longitude?: number | string; latitude?: number | string },
	graphicsLayer: any,
	picUrl: string,
	text?: string,
	offsetWidth = 0,
	offsetHeight = 0,
	fontColor = '#fff',
	svg = 20,
	fontSize = '14px',
	attrTemplate?: any,
	template?: any,
) {
	loadModules([
		'esri/symbols/PictureMarkerSymbol',
		'esri/symbols/Font',
		'esri/symbols/TextSymbol',
		'esri/graphic',
		'esri/geometry/Point',
	]).then(([ PictureMarkerSymbol, Font, TextSymbol, Graphic, Point ]) => {
		const longitude = data.longitude;
		const latitude = data.latitude;
		if (!longitude || !latitude || !text) {
			return;
		}
		const point = new Point(Number(longitude), Number(latitude));
		const pictureMarkerSymbol = new PictureMarkerSymbol(picUrl, text.length * svg, 30);
		pictureMarkerSymbol.setOffset(offsetWidth, offsetHeight);
		// 创建Graphic
		const graphicPic = new Graphic(point, pictureMarkerSymbol, attrTemplate, template);
		// 图层增加图片点
		graphicsLayer.add(graphicPic);
		const font = new Font();
		font.setSize(fontSize);
		const textSymbol = new TextSymbol(text || '--', font, fontColor);
		textSymbol.setOffset(offsetWidth, offsetHeight - 5);
		// 创建文字描述点
		const graphicText = new Graphic(point, textSymbol, attrTemplate, template);
		// 增加文字描述点
		graphicsLayer.add(graphicText);
	});
}

/**
 * 添加文字点位图层
 * @param data 点位数据
 * @param graphicsLayer 图层
 * @param picUrl 图片地址
 * @param text 文字描述
 * @param offsetWidth 图片偏移宽度
 * @param offsetHeight 图片偏移高度
 * @param attrTemplate 属性列表
 * @param infoTemplate 信息框
 */
export function addLabel(
	data: { longitude?: number | string; latitude?: number | string },
	graphicsLayer: any,
	text?: string,
	offsetWidth = 0,
	offsetHeight = 0,
	fontColor = '#333',
	svg = 13,
	fontSize = '14px',
	setHaloSize = 1,
	attrTemplate?: any,
	template?: any,
) {
	loadModules([
		'esri/symbols/Font',
		'esri/symbols/TextSymbol',
		'esri/graphic',
		'esri/geometry/Point',
		'esri/Color',
	]).then(([Font, TextSymbol, Graphic, Point, Color]) => {
		// console.log(attrTemplate, addLabel);
		const longitude = data.longitude;
		const latitude = data.latitude;
		if (!longitude || !latitude || !text) {
			return;
		}
		const point = new Point(Number(longitude), Number(latitude));
		const font = new Font(fontSize, {}, {}, Font.WEIGHT_BOLD, 'heiti');
		// font.setSize(fontSize);
		// font.setWeight(Font.WEIGHT_BOLD);
		const textSymbol = new TextSymbol(text || '--', font, fontColor);
		textSymbol.setOffset(offsetWidth, offsetHeight - 20);
		textSymbol.setHaloColor(new Color([255, 255, 255]));
		textSymbol.setHaloSize(setHaloSize);
		// 创建文字描述点
		const graphicText = new Graphic(point, textSymbol, attrTemplate, template);
		// 增加文字描述点
		graphicsLayer.add(graphicText);
	});
}

/**
 * @description: 设置中心点
 * @param {number} lon
 * @param {number} lat
 * @param {any} mapView 地图实例
 * @param {number} zoom 放大系数
 * @return {*}
 */
export function setCenter(lon: number | string, lat: number | string, mapView: any, zoom: number) {
	loadModules([ 'esri/geometry/Point' ]).then(([ Point ]) => {
		const point = new Point(Number(lon), Number(lat));
		mapView.centerAndZoom(point, zoom);
	});
}

/**
 * 添加圆
 * @param x x坐标
 * @param y y坐标
 * @param distance 辐射圈半径 单位：千米
 * @param layer 要添加到的图层对象
 * @return yuan
 */
export async function addCircle(x: any, y: any, distance: number, layer: { add: (arg0: any) => void }): Promise<any> {
	const [ Point, Circle, SimpleFillSymbol, SimpleLineSymbol, Color, Graphic ] = await loadModules([
		'esri/geometry/Point',
		'esri/geometry/Circle',
		'esri/symbols/SimpleFillSymbol',
		'esri/symbols/SimpleLineSymbol',
		'esri/Color',
		'esri/graphic',
	]);
	if (!x || !y) {
		return;
	}
	const point = new Point(Number(x), Number(y));
	const circleGeometry = new Circle(point, {
		radius: distance * 1000,
		geodesic: true,
	});
	const sms = new SimpleFillSymbol(
		SimpleFillSymbol.STYLE_SOLID,
		new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([ 22, 127, 255 ]), 3),
		new Color([ 22, 127, 255, 0.5 ]),
	);
	// console.log(layer);
	const graphic = new Graphic(circleGeometry, sms);
	layer.add(graphic);

	return graphic;
}

/**
 * 获取图层信息
 * @param layerId 图层ID
 * @param map 地图对象
 */
export function getLayer(map: any, layerId: string): Promise<any> {
	return new Promise((resolve, inject) => {
		resolve(map._layers[layerId]);
	});
}

/**
 * 添加地图边界
 * @param borderlineLayer 边界图层
 * @param data 数据
 */
export async function addBorderline(borderlineLayer: any, data: any, key = 'rings', areaColor = [22, 127, 255, 80], borderColor = [22, 127, 255], width = 1): Promise<any> {
	return new Promise((resolve, inject) => {
		loadModules(['ths/libs/jsonConverters', 'esri/graphic']).then(async ([jsonConverters, Graphic]) => {
			const converter = new jsonConverters.geoJsonConverter();
			const jsonObj = converter.toEsri(data, 4326);
			const { features } = jsonObj;
			// console.log(jsonObj);
			let ringsList: number[] = [];
			for (let i = 0; i < features.length; i++) {
				const feature = features[i];
				const symbol: any = [];
				if (symbol) {
					if (symbol.length) {
						feature.symbol = symbol[i];
					} else {
						feature.symbol = symbol;
					}
				}
			}
			console.log(features);
			const josn = features || [];
			josn.forEach((element: any) => {
				ringsList = ringsList.concat(element.geometry[key]);
				if (element.attributes.background) {
					areaColor = element.attributes.background
				}
				if (element.attributes.borderColor) {
					borderColor = element.attributes.borderColor
				}
				const lineData = {
					geometry: {
						paths: element.geometry[key],
						spatialReference: {
							wkid: 4326,
						},
					},
					attributes: element.attributes || {},
					symbol: {
						type: 'esriSFS',
						style: 'esriSFSSolid',
						color: areaColor,
						outline: {
							width: width,
							style: 'esriSFSSolid',
							type: 'esriSLS',
							color: borderColor,
						},
					},
				};
				const gra = new Graphic(lineData);
				borderlineLayer.add(gra);
			});
			resolve({ data: josn, oldData: data, ringsList });
		});
	});
}
/**
 * 添加地图边界
 * @param borderlineLayer 边界图层
 * @param data 数据
 */
export async function addGEOBorderline(borderlineLayer: any, geo: any): Promise<any> {
	return new Promise((resolve, inject) => {
		loadModules([ 'ths/libs/jsonConverters', 'esri/graphic' ]).then(async ([ jsonConverters, Graphic ]) => {
			let ringsList: number[] = [];
			// console.log('josn', josn);
			geo.coordinates.forEach((element: any) => {
				ringsList = ringsList.concat(element);
				const lineData = {
					geometry: {
						paths:element,
						spatialReference: {
							wkid: 4326,
						},
					},
					attributes: {
						ObjectID: 1.5,
						Name: '线',
					},
					symbol: {
						type: 'esriSFS',
						style: 'esriSFSSolid',
						color: [ 22, 127, 255, 80 ],
						outline: {
							width: 1,
							style: 'esriSFSSolid',
							type: 'esriSLS',
							color: [ 22, 127, 255 ],
						},
					},
				};
				const gra = new Graphic(lineData);
				borderlineLayer.add(gra);
			});
			resolve({ ringsList });
		});
	});
}
/**
 * 设置边界数据
 * @param data 数据
 */
export function setBorderLineData(data: any): Promise<any> {
	return new Promise((resolve, inject) => {
		loadModules([ 'ths/libs/jsonConverters' ]).then(async ([ jsonConverters ]) => {
			const converter = new jsonConverters.geoJsonConverter();
			const jsonObj = converter.toEsri(data, 4326);
			const { features } = jsonObj || [];
			// for (let i = 0; i < features.length; i++) {
			// 	const feature = features[i];
			// 	const symbol: any = [];
			// 	if (symbol) {
			// 		if (symbol.length) {
			// 			feature.symbol = symbol[i];
			// 		} else {
			// 			feature.symbol = symbol;
			// 		}
			// 	}
			// }
			resolve({ data: features, oldData: data });
		});
	});
}

/**
 * 单独添加边界
 * @param features
 * @param borderlineLayer
 */
export function borderLine(features: any, borderlineLayer: any, key = 'rings', areaColor = [22, 127, 255, 80], borderColor = [22, 127, 255], width = 1) {
	loadModules([ 'esri/graphic' ]).then(async ([ Graphic ]) => {
		const josn = features || [];
		josn.forEach((element: any) => {
			const lineData = {
				geometry: {
					paths: element.geometry[key],
					spatialReference: {
						wkid: 4326,
					},
				},
				attributes: {
					ObjectID: 1.5,
					Name: '线',
				},
				symbol: {
					type: 'esriSFS',
					style: 'esriSFSSolid',
					color: areaColor,
					outline: {
						width,
						style: 'esriSFSSolid',
						type: 'esriSLS',
						color: borderColor,
					},
				},
			};
			const gra = new Graphic(lineData);
			borderlineLayer.add(gra);
		});
	});
}

/**
 * 获取面的中心位置
 * @param listData 列表数据
 */
export function getAreaCenter(listData: any[]): Promise<any> {
	return new Promise((resolve, inject) => {
		loadModules([ 'ths/libs/turf.min', 'esri/graphic' ]).then(async ([ turf1, Graphic ]) => {
			const polygon = turf.polygon(listData);
			resolve(turf.centroid(polygon));
		});
	});
}

/**
 * 获取地图中心点
 * @param map 目标地图
 */
export function getCenter(map: any): { x: number; y: number } {
	return map.geographicExtent.getCenter();
}

/**
 * 设置缓冲区域
 * @param map 目标地图
 * @param x 经度
 * @param y 纬度
 * @param mapServerUrl 地图服务
 * @param layerIds 图层id
 * @param distance 缓冲半径
 * @param areaType 缓冲类型
 */
export function setBuffer(map: any, x: number, y: number, mapServerUrl: string, layerIds: number[] | string[], distance: number, areaType = 'kilometers') {
	return new Promise((resolve, inject) => {
		loadModules([
			'esri/geometry/geometryEngine',
			'esri/geometry/Point',
			'esri/tasks/IdentifyTask',
			'esri/tasks/IdentifyParameters',
		]).then(async ([ GeometryEngine, Point, IdentifyTask, IdentifyParameters ]) => {
			// 存放缓冲区运算结果的图形的图层
			// const bufferLayer = new GraphicsLayer({
			// 	title: '缓冲区图层',
			// });
			// map.addLayers([ bufferLayer ]);
			// bufferLayer.clear();
			const point = new Point(Number(x), Number(y)); // 当前点位
			const bufferGeometry = GeometryEngine.geodesicBuffer(point, distance, areaType); // 当前点位为圆形的geometry的缓冲区
			// console.log(bufferGeometry);
			const identifyTask = new IdentifyTask(mapServerUrl); // 创建多级图层查询任务
			const identifyParams = new IdentifyParameters(); // 创建多级任务查询参数
			identifyParams.geometry = bufferGeometry; //绘制的几何图形的geometry
			identifyParams.layerIds = layerIds; //需要被识别的图层的ID号, 支持查询多个,传入的图层名称，如[0, 1, 2, 3]
			identifyParams.returnGeometry = false; // 是否返回geometry
			identifyParams.tolerance = 3; // 屏幕像素与应被识别的几何体之间的距离
			identifyParams.mapExtent = map.extent; // 地图外框
			identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_ALL; // 配置查询全部图层，默认为top，查询最顶层图层
			identifyTask
				.execute(identifyParams)
				.then(function (response: any) {
					// console.log('response', response)
					resolve(response);
				})
				.catch((err: any) => {
					inject(err);
				});
		});
	});
}

/**
 * 重置面的渲染样式
 * @param mapServerUrl 地图服务
 * @param key 过滤属性key
 * @param value 过滤的值
 * @param layerId 图层ID
 */
export function resetRendener(mapServerUrl: string, key: string, value: string | number, layerId: string | number) {
	return new Promise((resolve, inject) => {
		loadModules([
			'esri/symbols/SimpleLineSymbol',
			'esri/symbols/SimpleFillSymbol',
			'esri/Color',
			'esri/renderers/UniqueValueRenderer',
			'esri/layers/FeatureLayer',
		]).then(([ SimpleLineSymbol, SimpleFillSymbol, Color, UniqueValueRenderer, FeatureLayer ]) => {
			const layer = new FeatureLayer(mapServerUrl + '/' + layerId, {
				outFields: [ key ],
			});
			console.log(layer);
			const defaultLineStyle = 'none',
				defaultColor = new Color([ 255, 0, 0, 0 ]),
				defaultLineWidth = 0;
			const defaultLineSymbol = new SimpleLineSymbol(defaultLineStyle, defaultColor, defaultLineWidth);
			const defaultFillSymbol = new SimpleFillSymbol(defaultLineStyle, defaultLineSymbol, defaultColor);
			const lineStyle = 'solid',
				lineWidth = 1.5;
			const lineSymbol = new SimpleLineSymbol(lineStyle, new Color([ 22, 127, 255 ]), lineWidth);
			const fillSymbol = new SimpleFillSymbol(lineStyle, lineSymbol, new Color([ 22, 127, 255, 0.5 ]));
			const renderer = new UniqueValueRenderer(defaultFillSymbol, key);
			renderer.addValue(value, fillSymbol);
			layer.setRenderer(renderer);
			resolve(layer);
		});
	});
}

/**
 * 重置面的渲染样式
 * @param mapServerUrl 地图服务
 * @param key 过滤属性key
 * @param value 过滤的值
 * @param layerId 图层ID
 */
export function resetSimpleRendener(key: string, value: string | number, layer: any) {
	return new Promise((resolve, inject) => {
		loadModules([
			'esri/symbols/SimpleLineSymbol',
			'esri/symbols/SimpleFillSymbol',
			'esri/Color',
			'esri/renderers/UniqueValueRenderer',
			'esri/layers/FeatureLayer',
		]).then(([ SimpleLineSymbol, SimpleFillSymbol, Color, UniqueValueRenderer, FeatureLayer ]) => {
			const defaultLineStyle = 'none',
				defaultColor = new Color([ 255, 0, 0, 0 ]),
				defaultLineWidth = 0;
			const defaultLineSymbol = new SimpleLineSymbol(defaultLineStyle, defaultColor, defaultLineWidth);
			const defaultFillSymbol = new SimpleFillSymbol(defaultLineStyle, defaultLineSymbol, defaultColor);
			const lineStyle = 'solid',
				lineWidth = 5;
			const lineSymbol = new SimpleLineSymbol(lineStyle, new Color([ 22, 127, 255 ]), lineWidth);
			const fillSymbol = new SimpleFillSymbol(lineStyle, lineSymbol, new Color([ 22, 127, 255, 0 ]));
			const renderer = new UniqueValueRenderer(defaultFillSymbol, key);
			renderer.addValue(value, fillSymbol);
			layer.setRenderer(renderer);
			resolve(layer);
		});
	});
}

export function resetAreaRendener(layer: any, attributeField: string, uvrJson:any) {
	return new Promise((resolve, inject) => { 
		loadModules([
			'esri/symbols/SimpleLineSymbol',
			'esri/symbols/SimpleFillSymbol',
			'esri/Color',
			'esri/renderers/UniqueValueRenderer',
			'esri/layers/FeatureLayer',
		]).then(([SimpleLineSymbol, SimpleFillSymbol, Color, UniqueValueRenderer, FeatureLayer]) => { 
			const renderer = new UniqueValueRenderer(uvrJson);
			layer.setRenderer(renderer);
		})
	})
}

/**
 * 重置线的渲染样式
 * @param mapServerUrl 地图服务
 * @param key 过滤属性key
 * @param value 过滤的值
 * @param layerId 图层ID
 */
export function resetLineRendener(mapServerUrl: string, key: string, value: string | number, layerId: string | number,lineSymbolColor = [ 22, 127, 255, 1 ], lineWidth = 3, id?: string) {
	return new Promise((resolve, inject) => {
		loadModules([
			'esri/symbols/SimpleLineSymbol',
			'esri/symbols/SimpleFillSymbol',
			'esri/Color',
			'esri/renderers/UniqueValueRenderer',
			'esri/layers/FeatureLayer',
		]).then(([ SimpleLineSymbol, SimpleFillSymbol, Color, UniqueValueRenderer, FeatureLayer ]) => {
			const layer = new FeatureLayer(mapServerUrl + '/' + layerId, {
				outFields: [ key ],
				id,
			});
			const defaultLineStyle = 'none',
				defaultColor = new Color([ 255, 0, 0, 0 ]),
				defaultLineWidth = 0;
			const defaultLineSymbol = new SimpleLineSymbol(defaultLineStyle, defaultColor, defaultLineWidth);
			const defaultFillSymbol = new SimpleFillSymbol(defaultLineStyle, defaultLineSymbol, defaultColor);
			const lineStyle = 'solid';
				// lineWidth = 3;
			// const lineSymbol = new SimpleLineSymbol(lineStyle, new Color('#99D5FF'), lineWidth);
			// const lineSymbol1 = new SimpleLineSymbol(lineStyle, new Color('#5174C5'), lineWidth);
			const lineSymbol = new SimpleLineSymbol(lineStyle, new Color(lineSymbolColor), lineWidth);
			const fillSymbol = new SimpleFillSymbol(lineStyle, lineSymbol, new Color([22, 127, 255, 0]));
			// const fillSymbol1 = new SimpleFillSymbol(lineStyle, lineSymbol1, new Color([ 22, 127, 255, 0 ]));
			const renderer = new UniqueValueRenderer(defaultFillSymbol, key);
			renderer.addValue(value, fillSymbol);
			// renderer.addValue(value, fillSymbol1);
			layer.setRenderer(renderer);
			resolve(layer);
		});
	});
}

/**
 * 叠加线图层
 * @param pathsData 线图层数据 [[116.2212,26.1123],[116.1212,26.0123]]
 * @param wkid 坐标系 102100 4326
 */
export function addPolyline(layer: any, pathsData: any[], color=[22, 127, 255], lineWidth = 5, wkid = 4326): Promise<any> {
	return new Promise((reslove) => {
		loadModules(['esri/geometry/Polyline', 'esri/graphic', 'esri/symbols/SimpleLineSymbol', 'esri/symbols/PictureMarkerSymbol','esri/symbols/PictureMarkerSymbol','esri/geometry/Point',]).then(([Polyline, Graphic, SimpleLineSymbol, PictureMarkerSymbol, Point]) => {
			const polylineJson = {
				'paths':[pathsData],
				'spatialReference':{wkid}
			};
			const sls = new SimpleLineSymbol(
				SimpleLineSymbol.STYLE_SOLID,
				color,
				lineWidth
			);
			const  polyline = new Polyline(polylineJson);
			const graphic = new Graphic(polyline, sls);
			layer.add(graphic);
			reslove('')
		});
	});
}

/**
 * 叠加面图层
 * @param ringsData 线图层数据 [[116.2212,26.1123],[116.1212,26.0123]]
 * @param wkid 坐标系 102100 4326
 */
export function addPolygon(layer: any, ringsData: any[], wkid = 4326, lineSymbolColor=[22, 127, 255], fillSymbolColor=[22, 127, 255, 0.5]): Promise<any>  {
	return new Promise((reslove) => {
		loadModules([
			'esri/graphic',
			'esri/geometry/Polygon',
			'esri/symbols/SimpleLineSymbol',
			'esri/symbols/SimpleFillSymbol',
			'esri/Color',
		]).then(([Graphic, Polygon, SimpleLineSymbol, SimpleFillSymbol, Color]) => {
			//面图层的数据
			const polygonJson = { rings: ringsData, spatialReference: { wkid } };
			const polygon = new Polygon(polygonJson);
			const lineStyle = 'solid',
				lineWidth = 3;
			const lineSymbol = new SimpleLineSymbol(lineStyle, new Color(lineSymbolColor), lineWidth);
			const fillSymbol = new SimpleFillSymbol(lineStyle, lineSymbol, new Color(fillSymbolColor));
			const graphic = new Graphic(polygon, fillSymbol);
			layer.add(graphic);
			reslove('')
		})
	});
}

/**
 * 转换地图坐标
 * @param x 屏幕坐标x
 * @param y 屏幕坐标y
 */
export function toMap(map: any, x: number, y: number): Promise<any> {
	return new Promise((resolve) => {
		loadModules([ 'esri/geometry/ScreenPoint' ]).then(([ ScreenPoint ]) => {
			const point = new ScreenPoint(x, y);
			const mapPoint = map.toMap(point);
			resolve(mapPoint);
		});
	});
}

/**
 * 转换屏幕坐标
 * @param x 地图坐标x
 * @param y 地图坐标y
 * @param wkid 坐标系
 */
export function toScreen(map: any, x: number, y: number, wkid: number): Promise<any>  {
	return new Promise((resolve) => {
		loadModules(['esri/geometry/Point']).then(([Point]) => {
			const point = new Point({ x:Number(x), y:Number(y), spatialReference: { wkid } });
			const screenPoint = map.toScreen(point);
			resolve(screenPoint);
		});
	});
}

/**
 * 获取区域面积
 * @param ringsData 轨迹数据
 * @returns 返回面积
 */
export function getArea(ringsData: number[]): Promise<number> {
	return new Promise((reslove) => {
		const polygon = turf.polygon([ ringsData ]);
		reslove(turf.area(polygon));
	});
}

/**
 * 计算轨迹距离
 * @param startPoint
 * @param endPoint
 * @param units
 * @returns
 */
export function getDistance(startPoint: number[], endPoint: number[], units = 'kilometers') {
	// console.log(startPoint, endPoint);
	const from = turf.point(startPoint);
	const to = turf.point(endPoint);
	const options = { units };
	// console.log(options)
	return turf.distance(from, to, options);
}

/**
 * 计算多线段轨迹距离
 * @param pointList
 * @param units 单位
 * @returns
 */
export function getPointDistance(pointList: number[][], units = 'kilometers') {
	const line = turf.lineString(pointList);
	return turf.length(line, {units});
}

/**
 * 计算多边形中心点
 * @param pointData
 */
export async function getCenterOfMass(pointData: any[]) {
	let list: any = [];
	if (pointData.length > 0) {
		pointData.forEach((item) => {
			const data = item.geometry.rings || [];
			list = [...data]
		});
		return getAreaCenter(list);
	}
}

/**
 * 计算多点中心点
 * @param pointData
 * @returns
 */
export function getLineCenter(pointData: number[]): Promise<{
	geometry: {
		coordinates: number[]
	}
}> {
	return new Promise((reslove) => {
		const points: any = [];
		pointData.forEach((item) => {
			points.push(turf.point(item));
		});
		const features = turf.featureCollection(points);
		const center = turf.center(features);
		reslove(center);
	});
}

export function drawHeatmap(
	map: any,
	field = 'point_code',
	pointListData: any[],
	colors: string[] = ["rgba(255, 0, 0, 0)", "rgb(0, 255, 0)", "rgb(255, 255, 0)", "rgb(255, 0, 0)"],
	wkid = 4326,
) {
	return new Promise((resolve) => {
		loadModules([
			'esri/layers/FeatureLayer',
			'esri/renderers/HeatmapRenderer',
			'esri/tasks/FeatureSet',	
			'esri/SpatialReference',
			'esri/graphic',
			'esri/geometry/Point'
		]).then(([FeatureLayer, HeatmapRenderer, FeatureSet, SpatialReference, Graphic, Point]) => {
			//热力图渲染
			const heatmapRenderer = new HeatmapRenderer(
				{
					colors,
					blurRadius: 10,
					maxPixelIntensity: 50,
					minPixelIntensity: 10
				}
			);
			const fieldAliases: any = {};
			const fields = [];
			for (const i in pointListData[0]){
				fieldAliases[i] = i;
				fields.push(
					{
						name: i,
                        type: i === field? 'esriFieldTypeOID' : 'esriFieldTypeInteger',
                        alias: i
					}
				);
			}
			const featureCollection = {
				layerDefinition: {
					fields,
					geometryType: "esriGeometryPoint",
				},
				featureSet: null
			};
			const heatMapLayer = new FeatureLayer(
				featureCollection,
				{
					outFields: ['*'],
					id: 'heatMapLayer',
					mode: FeatureLayer.MODE_SNAPSHOT,
					opacity: 1
				}
			);
			heatMapLayer.setRenderer(heatmapRenderer);
			map.addLayer(heatMapLayer);
			// pointListData.forEach((item: any) => {
			// 	const x = Number(item.attributes.ygjc_longitude);
			// 	const y = Number(item.attributes.ygjc_latitude);
			// 	const point = new Point(x, y, new SpatialReference({ wkid: 4326 }));
			// 	heatMapLayer.add(new Graphic(point));
			// });
			resolve(heatMapLayer);
		});
	});
}
